package com.loveprogrammer.lowercode.dna.service.impl;

import com.loveprogrammer.lowercode.common.ReturnMessage;
import com.loveprogrammer.lowercode.core.factory.KeyVaOperateFactory;
import com.loveprogrammer.lowercode.dna.common.CommonInfo;
import com.loveprogrammer.lowercode.dna.common.OperationFlagEnum;
import com.loveprogrammer.lowercode.dna.dao.InstDao;
import com.loveprogrammer.lowercode.dna.def.Dna;
import com.loveprogrammer.lowercode.dna.def.DnaDbMap;
import com.loveprogrammer.lowercode.dna.instance.bo.Cell;
import com.loveprogrammer.lowercode.dna.instance.bo.Inst;
import com.loveprogrammer.lowercode.dna.service.InstDMService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @ClassName InstDMServiceImpl
 * @Description TODO
 * @Author admin
 * @Date 2024/5/31 15:48
 * @Version 1.0
 */
@Service
public class InstDMServiceImpl implements InstDMService {

    @Autowired
    private DbMapCacheService dbMapCacheService;

    @Autowired
    private InstDao instDao;

    @Override
    public Inst saveInst(CommonInfo commonInfo, Inst inst) {
        if(inst == null || inst.getCells().size() == 0)
            return inst;
        if(inst.getDna() == null)
            throw new RuntimeException("inst 不存在Dna对象");

        Dna dna = inst.getDna();

        DnaDbMap dnaDbMap =  dbMapCacheService.getDnaDbMap(inst.getBusinessType(),dna.getDbMapCode());

        for (int i = inst.getCells().size() -1; i >=0 ; i--) {
            Cell cell = inst.getCells().get(i);
            if(cell.getOperationFlag().equals(OperationFlagEnum.DELETE.getCode())){
                this.instDao.deleteCell(cell);
                inst.getCells().remove(i);
            }
        }

        for (Cell cell : inst.getCells()) {
            if(cell.getOperationFlag().equals(OperationFlagEnum.ADD.getCode())){
                this.instDao.insertCell(cell,dnaDbMap);
            }
            else if(cell.getOperationFlag().equals(OperationFlagEnum.UPDATE.getCode())){
                this.instDao.updateCell(cell,dnaDbMap);
            }

            for (String childName : cell.getChildren().keySet()) {
                Inst childInst = cell.getChildInst(childName);
                this.saveInst(commonInfo,childInst);
            }
            cell.setOperationFlag(OperationFlagEnum.UNCHANGED.getCode());
        }
        return inst ;
    }

    @Override
    public ReturnMessage<Inst> getInst(CommonInfo commonInfo, Dna dna, Object cellKey) {
        Inst inst = this.instDao.getInst(dna,cellKey);
        getChildInst(commonInfo, inst);

        return ReturnMessage.ok(inst);
    }

    @Override
    public void getChildInst(CommonInfo commonInfo, Inst inst) {

        Dna dna = inst.getDna();
        DnaDbMap dnaDbMap = dbMapCacheService.getDnaDbMap(inst.getBusinessType(), dna.getDbMapCode());

        for (Cell cell : inst.getCells()) {

            Object cellKey = KeyVaOperateFactory.getKey(dnaDbMap, cell);

            for (Dna child : dna.getChildren()) {

                Inst childInst =  instDao.getInstByParentKey(child,cellKey);
                cell.addChildInst(child.getDnaName(), child.getDnaCode(), childInst);
                getChildInst(commonInfo,cell.getChildInst(child.getDnaName()));
            }
            if(dna.isCursive()) {
                Dna childDna = dna;
                Inst childInst = this.instDao.getInstByParentKey(childDna, cellKey);
                cell.addChildInst(childDna.getDnaName(),childDna.getDnaCode(),childInst);
                getChildInst(commonInfo, cell.getChildInst(childDna.getDnaName()));
            }
        }
    }

    @Override
    public void deleteInst(CommonInfo commonInfo, Dna dna, Object cellKey) {
        instDao.deleteCellByKey(cellKey,dna);
    }
}
